package com.pzhu.gmall.search.service.impl;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import com.pzhu.gmall.bean.PmsBaseAttrInfo;
import com.pzhu.gmall.dto.PmsSearchParmDTO;
import com.pzhu.gmall.dto.PmsSearchSkuInfoDTO;
import com.pzhu.gmall.nosql.PmsSearchSkuInfo;
import com.pzhu.gmall.service.AttributeService;
import com.pzhu.gmall.service.SearchService;
import com.pzhu.gmall.service.SkuInfoService;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;

/**
 * @author 刘鹏 liupeng
 * @date 2019/11/8
 **/
@Service
public class SearchServiceImpl implements SearchService {


    @Reference
    private SkuInfoService<PmsSearchSkuInfo> skuInfoService;

    @Reference
    private AttributeService attributeService;

    @Autowired
    private ElasticsearchRestTemplate restTemplate;

    String preTag = "<font color='#dd4b39'>";
    String postTag = "</font>";

    @Override
    public String searchInfoImport(List list) {
        List<PmsSearchSkuInfo> skuSearchInfoList = skuInfoService.getSkuSearchInfo();
        String result = "";
        for (PmsSearchSkuInfo pmsSearchSkuInfo : skuSearchInfoList) {
            IndexQuery query = new IndexQueryBuilder()
                    .withId(pmsSearchSkuInfo.getId())
                    .withObject(pmsSearchSkuInfo)
                    .build();
            result += restTemplate.index(query);
        }
        return result;
    }

    @Override
    public PmsSearchSkuInfoDTO search(PmsSearchParmDTO pmsSearchParmDTO) {
        SearchQuery searchQuery = createSearchQuery(pmsSearchParmDTO);
        AggregatedPage<PmsSearchSkuInfo> pmsSearchSkuInfos = restTemplate.queryForPage(searchQuery, PmsSearchSkuInfo.class);
        List<PmsSearchSkuInfo> searchSkuInfoList = pmsSearchSkuInfos.getContent();
        Set<String> valueIdSet = new HashSet<>();
        //从search结果中获取attrId的集合
        handleAttrIdSet(valueIdSet, searchSkuInfoList);

        List<PmsBaseAttrInfo> pmsBaseAttrInfoList = attributeService.getAttrinfoByValueIdSet(valueIdSet);
        PmsSearchSkuInfoDTO pmsSearchSkuInfoDTO = new PmsSearchSkuInfoDTO();
        pmsSearchSkuInfoDTO.setPmsBaseAttrInfoList(pmsBaseAttrInfoList);
        pmsSearchSkuInfoDTO.setSearchSkuInfoList(searchSkuInfoList);
        return pmsSearchSkuInfoDTO;
    }

    /**
     * 得到查询结果中的所有attrId
     *
     * @param valueIdSet
     * @param searchSkuInfoList
     */
    private void handleAttrIdSet(Set<String> valueIdSet, List<PmsSearchSkuInfo> searchSkuInfoList) {
        searchSkuInfoList.stream().map(s -> {
            Set<String> collect = s.getSkuAttrValueList().stream().map(v -> v.getValueId()).collect(Collectors.toSet());
            System.out.print(collect);
            return collect;
        }).forEach(s -> valueIdSet.addAll(s));
    }

    private SearchQuery createSearchQuery(PmsSearchParmDTO pmsSearchParmDTO) {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        if (!StringUtils.isBlank(pmsSearchParmDTO.getCatalog3Id())) {
            TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("catalog3Id", pmsSearchParmDTO.getCatalog3Id());
            queryBuilder.filter(termQueryBuilder);
        }
        String[] valueIds = pmsSearchParmDTO.getValueIds();
        if (valueIds != null) {
            Arrays.asList(valueIds).stream().forEach(valueId -> {
                TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("skuAttrValueList.valueId", valueId);
                queryBuilder.filter(termQueryBuilder);
            });
        }
        String keyword = pmsSearchParmDTO.getKeyword();
        if (!StringUtils.isBlank(keyword)) {
            MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("skuName", keyword);
            queryBuilder.must(matchQuery);
        }
        SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(queryBuilder)
                .withHighlightFields(new HighlightBuilder.Field("skuName").preTags(preTag).postTags(postTag))
                .build();
        searchQuery.setPageable(PageRequest.of(0, 100));
        return searchQuery;
    }
}
